#ifndef __SYNTAX_ERROR_LIST_H__
#define __SYNTAX_ERROR_LIST_H__

#include <string>

#define DECLARE_ERRORCODE_AND_INIT(x, y) \
    namespace cyclone::parser            \
    {                                    \
        char const x[] = y;              \
    };                                   \
    using cyclone::parser::x
#define DECLARE_ERRORCODE(x)  \
    namespace cyclone::parser \
    {                         \
        char const x[] = #x;  \
    };                        \
    using cyclone::parser::x

DECLARE_ERRORCODE(USE_KEYWORD_AS_IDENTIFIER);
DECLARE_ERRORCODE(USING_RESERVED_KEYWORD);

DECLARE_ERRORCODE_AND_INIT(RVALUE_IN_ASSIGNMENT_LEFT, "Assigning to rvalue");
DECLARE_ERRORCODE_AND_INIT(IDENTIFIER_DIRECTLY_AFTER_NUMBER, "Identifier directly after number");
DECLARE_ERRORCODE_AND_INIT(OPTIONAL_CHAIN_IN_LEFTHAND_SIDE, "Optional chaining cannot appear in left-hand side");
DECLARE_ERRORCODE_AND_INIT(UNTERMINATED_STRING, "Unterminated string constant");
DECLARE_ERRORCODE_AND_INIT(RETURN_OUTSIDE_FUNCTION, "return outside of function");
DECLARE_ERRORCODE_AND_INIT(MUST_INIT_CONST_DECLARATION, "Variable declaration with const must have an initial value");

DECLARE_ERRORCODE_AND_INIT(REST_ELEMENTS_CANNOT_HAVE_DEFAULT_VALUE, "Rest elements cannot have a default value");
DECLARE_ERRORCODE_AND_INIT(COMMA_NOT_PERMITTED_AFTER_REST_ELEMENT, "Comma is not permitted after the rest element");
DECLARE_ERRORCODE_AND_INIT(REDECLARATION_OF_IDENTIFIER, "`Identifier '${name}' has already been declared`");
DECLARE_ERRORCODE_AND_INIT(MIX_LOGICAL_AND_COALESCE, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); // NOTE   coalesce: "??" e.g b ?? a || b

DECLARE_ERRORCODE_AND_INIT(TODO0, "Redefinition of __proto__ property");
DECLARE_ERRORCODE_AND_INIT(TODO1, "Redefinition of property");
DECLARE_ERRORCODE_AND_INIT(TODO3, "Private identifier can only be left side of binary expression");
DECLARE_ERRORCODE_AND_INIT(TODO4, "Deleting local variable in strict mode");
DECLARE_ERRORCODE_AND_INIT(TODO5, "Private fields can not be deleted");
DECLARE_ERRORCODE_AND_INIT(TODO6, "Optional chaining cannot appear in the callee of new expressions");
DECLARE_ERRORCODE_AND_INIT(TODO7, "Cannot use 'await' as identifier inside an async function");
DECLARE_ERRORCODE_AND_INIT(TODO8, "Optional chaining cannot appear in the tag of tagged template expressions");
DECLARE_ERRORCODE_AND_INIT(TODO9, "'super' keyword outside a method");
DECLARE_ERRORCODE_AND_INIT(TODO10, "super() call outside constructor of a subclass");
DECLARE_ERRORCODE_AND_INIT(TODO11, "Escape sequence in keyword import");
DECLARE_ERRORCODE_AND_INIT(TODO12, "Trailing comma is not allowed in import()");
DECLARE_ERRORCODE_AND_INIT(TODO13, "The only valid meta property for import is 'import.meta'");
DECLARE_ERRORCODE_AND_INIT(TODO14, "'import.meta' must not contain escaped characters");
DECLARE_ERRORCODE_AND_INIT(TODO15, "Cannot use 'import.meta' outside a module");
DECLARE_ERRORCODE_AND_INIT(TODO16, "Comma is not permitted after the rest element");
DECLARE_ERRORCODE_AND_INIT(TODO17, "Escape sequence in keyword new");
DECLARE_ERRORCODE_AND_INIT(TODO18, "The only valid meta property for new is 'new.target'");
DECLARE_ERRORCODE_AND_INIT(TODO19, "'new.target' must not contain escaped characters");
DECLARE_ERRORCODE_AND_INIT(TODO20, "'new.target' can only be used in functions and class static block");
DECLARE_ERRORCODE_AND_INIT(TODO21, "Cannot use new with import()");
DECLARE_ERRORCODE_AND_INIT(TODO22, "Bad escape sequence in untagged template literal");
DECLARE_ERRORCODE_AND_INIT(TODO23, "Unterminated template literal");
DECLARE_ERRORCODE_AND_INIT(TODO24, "Comma is not permitted after the rest element");
DECLARE_ERRORCODE_AND_INIT(TODO25, "getter should have no params");
DECLARE_ERRORCODE_AND_INIT(TODO26, "setter should have exactly one param");
DECLARE_ERRORCODE_AND_INIT(TODO27, "Setter cannot use rest params");
DECLARE_ERRORCODE_AND_INIT(TODO28, "Illegal 'use strict' directive in function with non-simple parameter list");
DECLARE_ERRORCODE_AND_INIT(TODO29, "Cannot use 'yield' as identifier inside a generator");
DECLARE_ERRORCODE_AND_INIT(TODO30, "Cannot use 'await' as identifier inside an async function");
DECLARE_ERRORCODE_AND_INIT(TODO31, "Cannot use 'arguments' in class field initializer");
DECLARE_ERRORCODE_AND_INIT(TODO32, "Cannot use ${name} in class static initialization block");
DECLARE_ERRORCODE_AND_INIT(TODO33, "`Unexpected keyword '${name}'");
DECLARE_ERRORCODE_AND_INIT(TODO34, "Cannot use keyword 'await' outside an async function");
DECLARE_ERRORCODE_AND_INIT(TODO35, "The keyword '${name}' is reserved");
DECLARE_ERRORCODE_AND_INIT(TODO36, "Private field '#${node.name}' must be declared in an enclosing class");
DECLARE_ERRORCODE_AND_INIT(TODO37, "Cannot use 'await' as identifier inside an async function");
DECLARE_ERRORCODE_AND_INIT(TODO38, "Unexpected token");
DECLARE_ERRORCODE_AND_INIT(TODO41, "Only '=' operator can be used for specifying default value.");
// DECLARE_ERRORCODE_AND_INIT(TODO45,(isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
DECLARE_ERRORCODE_AND_INIT(TODO46, "let is disallowed as a lexically bound name");
DECLARE_ERRORCODE_AND_INIT(TODO47, "Argument name clash");
DECLARE_ERRORCODE_AND_INIT(TODO49, "Binding member expression");
DECLARE_ERRORCODE_AND_INIT(TODO50, "Binding parenthesized expression");
// DECLARE_ERRORCODE_AND_INIT(TODO51,(isBind ? "Binding" : "Assigning to") + " rvalue");
DECLARE_ERRORCODE_AND_INIT(TODO52, "Unexpected token");
DECLARE_ERRORCODE_AND_INIT(TODO53, "Comma is not permitted after the rest element");
DECLARE_ERRORCODE_AND_INIT(TODO54, "Parenthesized pattern");
DECLARE_ERRORCODE_AND_INIT(TODO55, "Shorthand property assignments are valid only in destructuring patterns");
DECLARE_ERRORCODE_AND_INIT(TODO56, "Redefinition of __proto__ property");
DECLARE_ERRORCODE_AND_INIT(TODO57, "Yield expression cannot be a default value");
DECLARE_ERRORCODE_AND_INIT(TODO58, "Await expression cannot be a default value");
DECLARE_ERRORCODE_AND_INIT(TODO59, "Invalid regular expression flag");
DECLARE_ERRORCODE_AND_INIT(TODO60, "Duplicate regular expression flag");
DECLARE_ERRORCODE_AND_INIT(TODO62, "Export '${name}' is not defined");
DECLARE_ERRORCODE_AND_INIT(TODO63, "'import' and 'export' may only appear at the top level");
DECLARE_ERRORCODE_AND_INIT(TODO64, "'import' and 'export' may appear only with 'sourceType: module'");
// DECLARE_ERRORCODE_AND_INIT(TODO65,"Unsyntactic  + $keyword");
DECLARE_ERRORCODE_AND_INIT(TODO66, "The left-hand side of a for-of loop may not start with 'let'.");
DECLARE_ERRORCODE_AND_INIT(TODO68, "Multiple default clauses");
DECLARE_ERRORCODE_AND_INIT(TODO69, "Illegal newline after throw");
DECLARE_ERRORCODE_AND_INIT(TODO70, "Missing catch or finally clause");
DECLARE_ERRORCODE_AND_INIT(TODO71, "'with' in strict mode");
DECLARE_ERRORCODE_AND_INIT(TODO72, "Label $maybeName is already declared");
DECLARE_ERRORCODE_AND_INIT(TODO74, "Complex binding patterns require an initialization value");
DECLARE_ERRORCODE_AND_INIT(TODO75, "Duplicate constructor in the same class");
DECLARE_ERRORCODE_AND_INIT(TODO76, "$Identifier '#${element.key.name}' has already been declared");
DECLARE_ERRORCODE_AND_INIT(TODO77, "Constructor can't have get/set modifier");
DECLARE_ERRORCODE_AND_INIT(TODO78, "Classes can't have an element named '#constructor'");
DECLARE_ERRORCODE_AND_INIT(TODO79, "Constructor can't be a generator");
DECLARE_ERRORCODE_AND_INIT(TODO80, "Constructor can't be an async method");
DECLARE_ERRORCODE_AND_INIT(TODO81, "Classes may not have a static property named prototype");
DECLARE_ERRORCODE_AND_INIT(TODO82, "getter should have no params");
DECLARE_ERRORCODE_AND_INIT(TODO83, "setter should have exactly one param");
DECLARE_ERRORCODE_AND_INIT(TODO84, "Setter cannot use rest params");
DECLARE_ERRORCODE_AND_INIT(TODO85, "Classes can't have a field named 'constructor'");
DECLARE_ERRORCODE_AND_INIT(TODO86, "Classes can't have a static field named 'prototype'");
DECLARE_ERRORCODE_AND_INIT(TODO87, "Private field '#${id.name}' must be declared in an enclosing class");
DECLARE_ERRORCODE_AND_INIT(TODO88, "Duplicate export $name");
DECLARE_ERRORCODE_AND_INIT(TODO89, "Escape sequence in keyword  $this.type.keyword");
// DECLARE_ERRORCODE_AND_INIT(TODO90,"Unterminated comment");
// DECLARE_ERRORCODE_AND_INIT(TODO91,"Unexpected character '" + codePointToString(code) + "'");
// DECLARE_ERRORCODE_AND_INIT(TODO92,"Unexpected character '" + codePointToString(code) + "'");
DECLARE_ERRORCODE_AND_INIT(TODO93, "Unterminated regular expression");
DECLARE_ERRORCODE_AND_INIT(TODO94, "Unterminated regular expression");
DECLARE_ERRORCODE_AND_INIT(TODO95, "Numeric separator is not allowed in legacy octal numeric literals");
DECLARE_ERRORCODE_AND_INIT(TODO96, "Numeric separator must be exactly one underscore");
DECLARE_ERRORCODE_AND_INIT(TODO97, "Numeric separator is not allowed at the first of digits");
DECLARE_ERRORCODE_AND_INIT(TODO98, "Numeric separator is not allowed at the last of digits");
DECLARE_ERRORCODE_AND_INIT(TODO99, "Expected number in radix  $radix");
DECLARE_ERRORCODE_AND_INIT(TODO102, "Invalid number");
DECLARE_ERRORCODE_AND_INIT(TODO110, "Unterminated template");

#endif // __SYNTAX_ERROR_LIST_H__
